PromQL 速查
本篇收录日常查询高频用到的选择器、必会函数和实战菜谱,随用随查。每条查询都可直接复制到 Web UI 或 Grafana 里跑,指标名按 node_exporter 和业务埋点的常见约定写,实际使用时换成你环境里的名字。
标签匹配选择器
四种匹配方式:
| 写法 | 含义 | 例子 |
|---|---|---|
= | 精确等于 | job="node" |
!= | 不等于 | mode!="idle" |
=~ | 正则匹配 | code=~"5.." |
!~ | 正则不匹配 | job!~"test.*" |
两种数据形态:
- 瞬时向量:
http_requests_total,取当前时刻的值 - 区间向量:
http_requests_total[5m],取最近 5 分钟的一段数据,rate类函数必须喂区间向量
必会函数
| 函数 | 用途 | 例子 |
|---|---|---|
rate() | counter 每秒增速,看趋势首选 | rate(http_requests_total[5m]) |
increase() | 区间内的总增量 | increase(http_requests_total[1h]) |
irate() | 取最后两个点算瞬时速率,灵敏但抖 | irate(node_cpu_seconds_total[5m]) |
sum() | 求和聚合 | sum by (job) (rate(http_requests_total[5m])) |
avg() | 平均聚合 | avg by (instance) (node_load1) |
max() | 最大值聚合 | max by (instance) (node_memory_MemAvailable_bytes) |
min() | 最小值聚合 | min by (instance) (node_memory_MemAvailable_bytes) |
topk() | 取值最大的前 N 条序列 | topk(5, node_load1) |
bottomk() | 取值最小的前 N 条序列 | bottomk(5, node_load1) |
histogram_quantile() | 从 histogram 桶估算分位数 | histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m]))) |
absent() | 指标不存在时返回 1,做「指标消失」告警 | absent(up{job="node"}) |
predict_linear() | 按区间数据线性外推,预测未来值 | predict_linear(node_filesystem_free_bytes[6h], 4*3600) |
rate 窗口的取法
rate(x[5m]) 里的窗口至少取抓取间隔的 2 到 4 倍。抓取间隔 30 秒的指标用 [5m] 窗口问题不大;用 [1m] 就会出现断线和锯齿。面板分辨率高也别把窗口压到间隔以下,PromQL 变不出不存在的采样点。
实战菜谱
| 场景 | 查询 | 说明 |
|---|---|---|
| CPU 使用率(%) | 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) | 用 100 减去空闲占比,按实例聚合 |
| 内存使用率(%) | 100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) | 用 MemAvailable 而不是 MemFree,前者才算真正可用 |
| 磁盘增长预测 | predict_linear(node_filesystem_free_bytes{fstype!="tmpfs"}[6h], 4*3600) < 0 | 按最近 6 小时趋势外推,小于 0 表示 4 小时内会写满 |
| QPS | sum(rate(http_requests_total[5m])) | counter 增速求和,全站每秒请求数 |
| 错误率(5xx 占比) | sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) | 分子分母保持同一聚合维度,结果乘 100 是百分比 |
| P99 延迟 | histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket[5m]))) | 必须先按 le 聚合再算分位,顺序不能反 |
| 有变化的序列 | changes(node_load1[24h]) > 0 | changes() 统计区间内值变动次数,找出活跃的序列 |
除法查询记得防零
错误率这类除法,分母为 0 的实例会直接消失而不是报错。如果需要「没流量也显示 0」,可以写成 sum(rate(errors[5m])) / sum(rate(total[5m])) or vector(0),用 or 兜底。